package com.hulytu.invasion;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArrayMap;

import com.hulytu.invasion.plugin.ActivityEnhancePlugin;
import com.hulytu.invasion.plugin.EnhancePlugin;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

class EnhanceStore {

    private final Map<String, EnhancePlugin<?>> pluginMap = new ArrayMap<>();

    private final List<EnhancePlugin<?>> plugins = new ArrayList<>();

    private final Map<String, Method> lifecycleMethodCache = new ArrayMap<>();

    EnhanceStore() {
        Class<?> clazz = ActivityEnhancePlugin.class;
        try {

            lifecycleMethodCache.put(ActivityEnhancePlugin.CREATE, clazz.getMethod(ActivityEnhancePlugin.CREATE, Activity.class, Bundle.class));

            String[] array = {
                    ActivityEnhancePlugin.RESUME,
                    ActivityEnhancePlugin.STOP,
                    ActivityEnhancePlugin.PAUSE,
                    ActivityEnhancePlugin.START,
                    ActivityEnhancePlugin.DESTROY,
            };

            for (String s : array) {
                lifecycleMethodCache.put(s, clazz.getMethod(s, Activity.class));
            }

            Collection<Method> methods = lifecycleMethodCache.values();
            for (Method method : methods) {
                method.setAccessible(true);
            }

        } catch (Exception e) {
            if (Planet.DEFAULT.isLoggable()) e.printStackTrace();
        }
    }

    List<EnhancePlugin<?>> filterAndRegister(List<EnhancePlugin<?>> src) {
        for (EnhancePlugin<?> plugin : src) {
            if (registerPlugin(plugin)) plugins.add(plugin);
        }

        return plugins;
    }

    List<EnhancePlugin<?>> plugins() {
        return plugins;
    }

    /**
     * 注册插件
     *
     * @param plugin
     * @return
     */
    private boolean registerPlugin(EnhancePlugin<?> plugin) {
        String name = plugin.pluginName();
        EnhancePlugin<?> cache = pluginMap.get(name);

        if (cache == plugin) return false;

        if (cache == null && plugin.isCompatible()) {
            pluginMap.put(name, plugin);
            return true;
        }

        return false;
    }

    @SuppressWarnings("unchecked")
    <T> EnhancePlugin<T> findPlugin(String plugin) {
        return (EnhancePlugin<T>) pluginMap.get(plugin);
    }

    void onActivityLifecycleCallback(String name, Object... args) {
        for (EnhancePlugin<?> plugin : plugins) {
            if (plugin instanceof ActivityEnhancePlugin) {
                lifecycle(name, (ActivityEnhancePlugin<?>) plugin, args);
            }
        }
    }

    void lifecycle(String name, ActivityEnhancePlugin<?> plugin, Object... args) {
        if (args.length < 1) return;

        Class<?> clazz = plugin.getHostClass();

        Object arg0 = args[0];
        if (arg0 == null
                || clazz == null
                || TextUtils.isEmpty(name)
                || !clazz.isAssignableFrom(arg0.getClass()))
            return;

        Method method = lifecycleMethodCache.get(name);
        if (method != null) {
            try {
                method.invoke(plugin, args);
            } catch (Exception e) {
                if (Planet.DEFAULT.isLoggable()) e.printStackTrace();
            }
        }

    }
}
